import re
import sys
from PyQt5 import QtGui
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QCheckBox, QLineEdit, QRadioButton, QGridLayout, \
    QPushButton, QTableWidget, QApplication, QTableWidgetItem, QSplashScreen, QFileDialog, QComboBox, QMessageBox

from cg_main.codeEntity import CodeEntity
from cg_main.codeTools import CodeTools
from cg_main.uistyle import setStyle
from pop.main import DialogTemplate
from word.main import WordGenerate


class BaseUi(QWidget):
    def __init__(self, parent=None):
        super(BaseUi, self).__init__(parent)
        self.resize(800, 600)
        self.status = {}
        self.word=None
        self.init()
        self.setWindowIcon(QIcon("./images/title.ico"))
        self.setWindowTitle("auth:韦定兴  qq:717293846")
        pix = QPixmap("./images/pro.jpg")
        palate = QtGui.QPalette()
        palate.setBrush(QtGui.QPalette.Background, QtGui.QBrush(pix))
        self.setPalette(palate)
        imageLabel = QLabel()
        imageLabel.setPixmap(pix)
        hbox = QHBoxLayout()
        hbox.addWidget(self.fun)
        hbox.addWidget(self.qtable)
        qw1 = QWidget()
        qw1.setLayout(hbox)
        vbox = QVBoxLayout()
        vbox.addWidget(self.fileWidget)
        vbox.addWidget(qw1)
        vbox.addWidget(self.inputFun)
        self.setStyleSheet(setStyle())
        self.setLayout(vbox)
        self._pysigner()

    def init(self):
        self.widgetTable()
        self.funWidget()
        self.funWidget1()
        self.selectfileWidget()

    #
    def funWidget1(self):
        self.inputFun = QWidget()
        self.inputFun.resize(100, 100)
        qh = QHBoxLayout()
        self.isInterface = QCheckBox("接口")
        self.isInterface.setStyleSheet("color:white;font-size:14px")
        qlname = QLabel("类名｜接口名:")
        self._className = QLineEdit()
        qlname.setStyleSheet("color:white")
        self._class = QRadioButton("类")
        self._class.setChecked(True)
        self.interface = QRadioButton("接口")
        self._class.setStyleSheet("color:red;font-size:14px")
        self.interface.setStyleSheet("color:red;font-size:14px")
        fa = QLabel("父类:")
        fa.setStyleSheet("color:white")
        self.father = QLineEdit()
        self.father.setStyleSheet("max-width:100px;min-height:30;margin-right:100px")
        self._className.setStyleSheet("max-width:100px;min-height:30;")
        self.notice = QLabel("欢迎使用vk代码生成工具")
        self.notice.setStyleSheet("color:red;min-width:180px")
        qh.addWidget(self.isInterface)
        qh.addWidget(qlname)
        qh.addWidget(self._className)
        qh.addWidget(self._class)
        qh.addWidget(self.interface)
        qh.addWidget(fa)
        qh.addWidget(self.father)
        qh.addWidget(self.notice)
        self.inputFun.setLayout(qh)

    def selectfileWidget(self):
        self.fileWidget = QWidget()
        qh = QHBoxLayout()
        self.filePath.setPlaceholderText("word文件路径")
        self.filePath.setStyleSheet("min-height:30px")
        self.viewTemp = QPushButton("查看模版")
        self.viewTemp.setToolTip("查看读取的word格式")
        self.addFile = QPushButton("添加文件")
        self.enbleTables=QComboBox()
        self.enbleTables.addItem("可用表格")
        self.enbleTables.setVisible(False)
        self.genrateTable = QPushButton("生成字段")
        self.genrateTable.setVisible(False)
        self.addTag = QCheckBox("添加备注")
        self.addTag.setToolTip("勾选后可添加注释到代码")
        self.addTag.setStyleSheet("color:white;font-size:14px")
        qh.addWidget(self.filePath)
        qh.addWidget(self.addFile)
        qh.addWidget(self.enbleTables)
        qh.addWidget(self.genrateTable)
        qh.addWidget(self.addTag)
        qh.addWidget(self.viewTemp)
        self.fileWidget.setLayout(qh)

    def funWidget(self):
        self.fun = QWidget()
        self.fun.resize(400, 800)
        background = QtGui.QPixmap('./images/program1.jpg')
        palete = QtGui.QPalette()
        background.scaled(50, 50)
        palete.setBrush(self.fun.backgroundRole(), QtGui.QBrush(background))
        self.fun.setPalette(palete)
        self.fun.setAutoFillBackground(True)
        grid = QGridLayout()
        grid.setSpacing(10)
        self.clear = QPushButton("清空内容")
        self.clear.setToolTip("清空表格所有内容")
        self.addRow = QPushButton("添加一行")
        self.tuoFeng = QPushButton("转为驼峰")
        self.underline = QPushButton("转下划线")
        self.genrate = QPushButton("生成代码")
        self.filePath = QLineEdit()
        grid.addWidget(self.clear, 0, 0)
        grid.addWidget(self.addRow, 0, 1)
        grid.addWidget(self.tuoFeng, 3, 0, 1, 1)
        grid.addWidget(self.underline, 3, 1, 1, 1)
        grid.addWidget(self.genrate, 4, 1, 1, 1)
        self.fun.setLayout(grid)

    def _pysigner(self):
        self.clear.clicked.connect(self.clearTable)
        self.addRow.clicked.connect(self.addRows)
        self.genrate.clicked.connect(self.getTableData)
        self.addFile.clicked.connect(self.selectFile)
        self.genrateTable.clicked.connect(self.genrateTableData)
        self.tuoFeng.clicked.connect(self.changeForTF)
        self.underline.clicked.connect(self.changeForUnderline)
        self.viewTemp.clicked.connect(self.viewTemplate)
        self.enbleTables.highlighted.connect(self.genrateTableData)

    def viewTemplate(self):
        template = DialogTemplate()
        template.showdialog()

    def changeForTF(self):
        count = self.qtable.rowCount()
        for i in range(count):
            data = self.setCodeEntity(self.qtable.item(i, 0))
            if data is None:
                continue
            tfData = self.generateTf(data)
            if tfData is None:
                continue
            self.qtable.setItem(i, 0, QTableWidgetItem(tfData))

    def changeForUnderline(self):
        count = self.qtable.rowCount()
        for i in range(count):
            data = self.setCodeEntity(self.qtable.item(i, 0))
            if data is None:
                continue
            tfData = self.humpToUnderline(data)
            if tfData is None:
                continue
            self.qtable.setItem(i, 0, QTableWidgetItem(tfData))

    def humpToUnderline(self, text):
        res = []
        for index, char in enumerate(text):
            if char.isupper() and index != 0:
                res.append("_")
            res.append(char)
        return ''.join(res).lower()

    def generateTf(self, filed):
        if "_" in filed:
            hump = self.convert(filed, "_")
            return hump
        if "-" in filed:
            hump = self.convert(filed, "_")
            return hump
        return None

    def convert(self, one_string, space_character):  # one_string:输入的字符串；space_character:字符串的间隔符，以其做为分隔标志

        string_list = str(one_string).split(space_character)  # 将字符串转化为list
        first = string_list[0].lower()
        others = string_list[1:]
        others_capital = [word.capitalize() for word in others]  # str.capitalize():将字符串的首字母转化为大写
        others_capital[0:0] = [first]
        hump_string = ''.join(others_capital)  # 将list组合成为字符串，中间无连接符。
        return hump_string

    def clearTable(self):
        self.qtable.clearContents()
        self.status.clear()
        self.qtable.viewport().update()

    def addRows(self):
        lastRow = self.qtable.rowCount()
        self.qtable.insertRow(lastRow)
        self.qtable.viewport().update()

    def widgetTable(self):
        self.qtable = QTableWidget()
        self.qtable.setObjectName("qtable")
        self.qtable.setColumnCount(5)
        self.qtable.setRowCount(20)
        self.qtable.resizeRowsToContents()
        self.qtable.setHorizontalHeaderLabels(['字段', '类型', '权限', '备注', 'enable'])
        self.qtable.verticalHeader().sectionClicked.connect(self.deteleCurrentRow)
        self.qtable.setToolTip("点击可删除此行")
        self.qtable.currentItemChanged.connect(self.autoSetitem)

    def autoSetitem(self, new, old):
        if old is None:
            return
        currentRow = old.row()
        data = self.qtable.item(currentRow, 0)
        data1 = self.qtable.item(currentRow, 2)
        if data is not None and data1 is not None:
            return
        currentData=self.qtable.item(currentRow,0)
        if currentData is not None and len(currentData.text()) >0:
            self.qtable.setItem(currentRow, 2, QTableWidgetItem("private"))
            self.qtable.setItem(currentRow, 1, QTableWidgetItem("String"))
            self.qtable.setItem(currentRow, 3, QTableWidgetItem(""))
            enable = QCheckBox()
            enable.setChecked(True)
            enable.setStyleSheet(setStyle())
            self.status[currentRow] = enable
            self.qtable.setCellWidget(currentRow, 4, enable)
            self.qtable.viewport().update()

    def state(self, sen):
        # if sen.isChecked()
        pass

    def deteleCurrentRow(self):
        index = self.qtable.selectedRanges()
        index = index[0].bottomRow()
        self.qtable.removeRow(index)
        self.qtable.viewport().update()
        try:
            self.status.pop(index)
        except:
            pass

    def getTableData(self):
        codeDict = {}
        className = self._className.text()
        if className == "":
            print("类名不能为空")
            QMessageBox.information(self, "提示", "类名不能为空", QMessageBox.Ok)
            return
        result = re.match("[0-9]", className[0])
        if result is not None:
            QMessageBox.information(self, "提示", "类名不能以数字开头", QMessageBox.Ok)
            return
        for i in range(self.qtable.rowCount()):
            try:
                statusEnable = self.status.get(i)
                if not statusEnable.isChecked():
                    continue
            except Exception as e:
                pass
            try:
                name = self.setCodeEntity(self.qtable.item(i, 0))
                if name is None:
                    continue
                NameType = self.setCodeEntity1(self.qtable.item(i, 1))
                promise = self.setCodeEntity1(self.qtable.item(i, 2))
                tag = self.setCodeEntity1(self.qtable.item(i, 3))
                code = CodeEntity(name=name, nameType=NameType, promise=promise, tag=tag)
                codeDict[i] = code
            except Exception as e:
                print(e)

        fatherClass = None
        if self.father.text() != "":
            fatherClass = self.father.text()
        elif self.father.text() != "" and re.match("[0-9]]", (self.father.text())[0]) is not None:
            print("类名不能以数字开头")
            QMessageBox.information(self, "提示", "类名不能以数字开头", QMessageBox.Ok)

            return
        extendsType = None
        if self._class.isChecked():
            extendsType = "extends"
        else:
            extendsType = "implements"
        isClass = "class"
        if self.isInterface.isChecked():
            isClass = "interface"
        try:
            self.notice.setText('创建中.....')
            CodeTools(codeEntity=codeDict, codeName=className, extendsType=extendsType, fatherClass=fatherClass,
                      isclass=isClass).genrateCode()
            QMessageBox.information(self, "提示", "创建成功", QMessageBox.Ok)
            self.notice.setText('欢迎使用vk代码生成工具')
        except Exception as e:
            print(e)
            QMessageBox.information(self, "提示", "创建失败", QMessageBox.Ok)
            self.notice.setText('欢迎使用vk代码生成工具')

    def setCodeEntity(self, table):
        if table is not None:
            return table.text()
        else:
            return None

    def setCodeEntity2(self, table):
        if table is not None:
            return table
        else:
            return None

    def setCodeEntity1(self, table):
        if table is not None:
            return table.text()
        else:
            return ""

    '''
     选择word文件
    '''

    def selectFile(self):
        try:
            fileName, fileType = QFileDialog.getOpenFileName(self, "选择word", "*.docx;;*.doc")
            print(fileName)
            if fileName is None:
                return
            self.filePath.setText(fileName)
            self.word = WordGenerate(self.filePath.text())
            tables = self.word.getTables()
            self.enbleTables.clear()
            self.enbleTables.addItem("可用表格")
            self.qtable.clearContents()
            for i in range(tables):
                self.enbleTables.addItem("table" + str(i + 1))
            self.enbleTables.setVisible(True)
        except Exception as e:
            print(e)


    '''
        从word表格生成字段
    '''

    def genrateTableData(self,index):
        if index==0:
            self.qtable.clearContents()
            self.qtable.viewport().update()
            return
        if self.filePath.text() == "":
            QMessageBox.information(self, "提示", "文件路径不能为空", QMessageBox.Ok)
            return
        if self.word is None:
            self.word = WordGenerate(self.filePath.text())
        tables = self.word.getWordTableData(index-1)
        if tables is None:
           QMessageBox.information(self, "提示", "word无表格数据", QMessageBox.Ok)
           return
        j = 0
        self.status.clear()
        self.qtable.clearContents()
        for i in tables:
            codeEntity = tables[i]
            self.qtable.setItem(j, 0, QTableWidgetItem(str(codeEntity.filedName)))
            self.qtable.setItem(j, 1, QTableWidgetItem(str(codeEntity.filedType)))
            self.qtable.setItem(j, 2, QTableWidgetItem(str('private')))
            if self.addTag.isChecked():
                desc = str(codeEntity.desc).replace("\n", " ")
                desc1 = desc.split('示例值')[0]
                self.qtable.setItem(j, 3, QTableWidgetItem(str(desc1)))
            enable = QCheckBox()
            enable.setChecked(True)
            enable.setStyleSheet(setStyle())
            self.status[j] = enable
            self.qtable.setCellWidget(j, 4, enable)
            self.qtable.viewport().update()
            j += 1
            if j >= self.qtable.rowCount():
                self.addRows()
                self.qtable.viewport().update()
        self.enbleTables.setCurrentIndex(index)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    splsh = QSplashScreen(QPixmap('./images/program.jpg'))
    splsh.show()
    app.processEvents()
    base = BaseUi()
    base.show()
    splsh.finish(base)
    sys.exit(app.exec_())
